package com.hsav.kcxb.activity;

import android.Manifest;
import android.app.Fragment;
import android.app.FragmentManager;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.media.MediaPlayer;
import android.media.MediaRecorder;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.support.v4.app.ActivityCompat;
import android.support.v7.app.AlertDialog;
import android.view.View;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;
import android.widget.VideoView;

import com.github.florent37.camerafragment.CameraFragment;
import com.github.florent37.camerafragment.configuration.Configuration;
import com.github.florent37.camerafragment.listeners.CameraFragmentResultListener;
import com.github.florent37.camerafragment.listeners.CameraFragmentStateAdapter;
import com.hsav.kcxb.R;
import com.hsav.kcxb.fragment.sing.AdjustVolumeFragment;
import com.hsav.kcxb.fragment.sing.PlayListFragment;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;

import me.wcy.lrcview.LrcView;

public class RunningRecordActivity extends BaseActivity implements
        View.OnClickListener, MediaPlayer.OnCompletionListener,
        MediaPlayer.OnPreparedListener, CameraFragmentResultListener,
        PlayListFragment.OnFragmentInteractionListener, AdjustVolumeFragment.OnFragmentInteractionListener {
    private static final String TAG = RunningRecordActivity.class.getName();
    private static final String ACTION_RECORD_AUDIO = "com.hsav.kcxb.action.record_audio";
    private static final String ACTION_RECORD_VIDEO = "com.hsav.kcxb.action.record_video";
    private VideoView videoView;
    private FrameLayout frameVideoContainer;
    private LrcView lrcView;
    private MediaRecorder mediaRecorder = new MediaRecorder();
    private Handler handler = new Handler();
    private Runnable runnable = new Runnable() {
        @Override
        public void run() {
            if (videoView.isPlaying()) {
                long time = videoView.getCurrentPosition();
                lrcView.updateTime(time);
            }

            handler.postDelayed(this, 100);
        }
    };
    private CameraFragmentStateAdapter stateAdapter = new CameraFragmentStateAdapter()
    {
        @Override
        public void onCameraSetupForVideo() {
            super.onCameraSetupForVideo();
            try {
                launch();
            } catch (IOException e) {
                e.printStackTrace();
            }
            //// TODO: 2017/6/23
            Toast.makeText(RunningRecordActivity.this, "On Camera Setup For Video.", Toast.LENGTH_SHORT).show();
        }
    };
    private String action = ACTION_RECORD_VIDEO;
    private CameraFragment cameraFragment;
    private TextView textTime;
    private TextView textTimeTotal;
    private FrameLayout fragmentContainer;
    private PlayListFragment playlistFragment;
    private AdjustVolumeFragment adjustVolumeFragment;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
//        action = getIntent().getAction();
        setContentView(R.layout.activity_running_record);
        prepareTestData();
        initView();
        if (ACTION_RECORD_AUDIO.equals(action)) {
            initForRecordAudio();
            try {
                launch();
            } catch (IOException e) {
                e.printStackTrace();
            }
        } else if (ACTION_RECORD_VIDEO.equals(action)) {
            initForRecordVideo();
        }
    }

    private void launch() throws IOException {
        File file = new File(getApplication().getCacheDir(), "cbg.mp3");
        videoView.setVideoPath(file.getAbsolutePath());
        videoView.start();
        if (ACTION_RECORD_VIDEO.equals(action))
        {
            cameraFragment.takePhotoOrCaptureVideo(this, Environment.getExternalStorageDirectory().getAbsolutePath(), "UserRecord");
        }
        else if (ACTION_RECORD_AUDIO.equals(action))
        {
            mediaRecorder.prepare();
            mediaRecorder.start();
        }
    }

    private void initForRecordAudio() {
        mediaRecorder = new MediaRecorder();
        mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
        mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
        mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
        File file = new File(Environment.getExternalStorageDirectory(), "UserRecord.amr");
        if (!file.exists())
            try {
                file.createNewFile();
            } catch (IOException e) {
                e.printStackTrace();
            }
        mediaRecorder.setOutputFile(file.getAbsolutePath());
    }

    private void initForRecordVideo() {
        if (ActivityCompat.checkSelfPermission(this, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
            // TODO: Consider calling
            //    ActivityCompat#requestPermissions
            // here to request the missing permissions, and then overriding
            //   public void onRequestPermissionsResult(int requestCode, String[] permissions,
            //                                          int[] grantResults)
            // to handle the case where the user grants the permission. See the documentation
            // for ActivityCompat#requestPermissions for more details.
            return;
        }
        Configuration configuration = new Configuration.Builder()
                .setCamera(Configuration.CAMERA_FACE_FRONT)
                .setMediaAction(Configuration.MEDIA_ACTION_VIDEO)
                .build();
        cameraFragment = CameraFragment.newInstance(configuration);
        cameraFragment.setStateListener(stateAdapter);
        getSupportFragmentManager().beginTransaction()
                .add(R.id.frame_video_container, cameraFragment, "VideoCaptureView")
                .commit();
    }

    private boolean prepareTestData() {
        String lrcPath = "cbg.lrc";
        String mp3Path = "cbg.mp3";
        File lrcFile = new File(getApplication().getCacheDir(), lrcPath);
        File mp3File = new File(getApplication().getCacheDir(), mp3Path);

        boolean hasError = false;
        try
        {
            if (!lrcFile.exists())
                lrcFile.createNewFile();
            if (!mp3File.exists())
            {
                mp3File.createNewFile();
            }
        }
        catch (IOException e)
        {
            hasError = true;
            e.printStackTrace();
        }
        if (hasError) return false;

        InputStream in = null;
        FileOutputStream out = null;
        try
        {
            in = getAssets().open(lrcPath);
            out = new FileOutputStream(lrcFile);
            int n;
            byte[] buf = new byte[10240];
            while ((n = in.read(buf)) != -1)
            {
                out.write(buf, 0, n);
            }
        }
        catch (IOException e)
        {
            hasError = true;
            e.printStackTrace();
        }
        finally {
            if (in != null)
            {
                try {
                    in.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (out != null)
            {
                try {
                    out.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        if (hasError) return false;
        try
        {
            in = getAssets().open(mp3Path);
            out = new FileOutputStream(mp3File);
            int n;
            byte[] buf = new byte[10240];
            while ((n = in.read(buf)) != -1)
            {
                out.write(buf, 0, n);
            }
        }
        catch (IOException e)
        {
            hasError = true;
            e.printStackTrace();
        }
        finally {
            if (in != null)
            {
                try {
                    in.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (out != null)
            {
                try {
                    out.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return !hasError;
    }

    private void initView() {
        fragmentContainer = (FrameLayout)findViewById(R.id.fragment_container);
        fragmentContainer.setVisibility(View.GONE);

        videoView = (VideoView)findViewById(R.id.videoView);
        videoView.setOnCompletionListener(this);
        videoView.setOnPreparedListener(this);

        lrcView = (LrcView)findViewById(R.id.lrc);
        lrcView.loadLrc(new File(getApplication().getCacheDir(), "cbg.lrc"));

        frameVideoContainer = (FrameLayout) findViewById(R.id.frame_video_container);
        if (ACTION_RECORD_AUDIO.equals(action))
            frameVideoContainer.setVisibility(View.GONE);

        textTime = (TextView)findViewById(R.id.text_time);
        textTime.setText("00:00");
        textTimeTotal = (TextView)findViewById(R.id.text_time_total);
        textTimeTotal.setText("03:00");

        ImageView imgBack = (ImageView) findViewById(R.id.img_back);
        imgBack.setOnClickListener(this);

        TextView textTitle = (TextView) findViewById(R.id.text_title);
        textTitle.setText("演员");

        ImageView imgPlayerList = (ImageView) findViewById(R.id.img_play_list);
        imgPlayerList.setOnClickListener(this);

        ImageView imgToClip = (ImageView) findViewById(R.id.img_to_clip);
        imgToClip.setOnClickListener(this);

        ImageView imgAgain = (ImageView) findViewById(R.id.img_again);
        imgAgain.setOnClickListener(this);

        ImageView imgVolume = (ImageView) findViewById(R.id.img_volume);
        imgVolume.setOnClickListener(this);

        TextView textStop = (TextView) findViewById(R.id.text_stop);
        textStop.setOnClickListener(this);
    }

    private String getLrcText(String fileName) {
        String lrcText = null;
        try {
            InputStream is = new FileInputStream(fileName);
            int size = is.available();
            byte[] buffer = new byte[size];
            is.read(buffer);
            is.close();
            lrcText = new String(buffer);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return lrcText;
    }

    @Override
    public void onClick(View v) {
        // TODO: 2017/6/13
        switch (v.getId())
        {
            case R.id.img_to_clip:
                startActivity(new Intent(this, MusicClipActivity.class));
                break;
            case R.id.img_again:
                AlertDialog.Builder builder = new AlertDialog.Builder(this);
                builder.setTitle("提示");
                builder.setMessage("当前歌曲还没有保存，确定重新录制吗？");
                builder.setPositiveButton("确定", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        Toast.makeText(RunningRecordActivity.this, "用户点击了确定按钮", Toast.LENGTH_SHORT).show();
                    }
                });
                builder.setNegativeButton("取消", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        Toast.makeText(RunningRecordActivity.this, "用户点击了取消按钮", Toast.LENGTH_SHORT).show();
                    }
                });
                builder.show();
                break;
            case R.id.img_volume:
                showSettingsView();
                break;
            case R.id.text_stop:
                startActivity(new Intent(this, ScoreActivity.class));
                break;
            case R.id.img_back:
                finish();
                break;
            case R.id.img_play_list:
                showPlaylist();
                break;
        }
    }

    private void showSettingsView() {
        fragmentContainer.setVisibility(View.VISIBLE);
        adjustVolumeFragment = AdjustVolumeFragment.newInstance(4, 60);
        FragmentManager fragMgr = getFragmentManager();
        fragMgr.beginTransaction().add(R.id.fragment_container, adjustVolumeFragment).commit();
    }

    private void showPlaylist() {
        fragmentContainer.setVisibility(View.VISIBLE);
        playlistFragment = PlayListFragment.newInstance("", "");
        FragmentManager fragMgr = getFragmentManager();
        fragMgr.beginTransaction().add(R.id.fragment_container, playlistFragment).commit();
    }

    @Override
    public void onBackPressed() {
        if (playlistFragment != null || adjustVolumeFragment != null)
        {
            FragmentManager fragMgr = getFragmentManager();
            if (playlistFragment != null)
                fragMgr.beginTransaction().remove(playlistFragment).commit();
            else if (adjustVolumeFragment != null)
                fragMgr.beginTransaction().remove(adjustVolumeFragment).commit();
            fragmentContainer.setVisibility(View.GONE);
            return;
        }
        mediaRecorder.stop();
        super.onBackPressed();
    }

    @Override
    protected void onPause() {
        super.onPause();
    }

    @Override
    protected void onDestroy() {
        mediaRecorder.release();
        super.onDestroy();
    }

    @Override
    public void onCompletion(MediaPlayer mp) {
        lrcView.onDrag(0);
        handler.removeCallbacks(runnable);
    }

    @Override
    public void onPrepared(MediaPlayer mp) {
        handler.post(runnable);
    }

    @Override
    public void onVideoRecorded(String filePath) {
        Toast.makeText(this, String.format("Video recorded and saved at %s", filePath), Toast.LENGTH_SHORT).show();
    }

    @Override
    public void onPhotoTaken(byte[] bytes, String filePath) {

    }

    @Override
    public void onRequestClose(Fragment sender) {
        FragmentManager fragMgr = getFragmentManager();
        fragMgr.beginTransaction().remove(sender).commit();
        fragmentContainer.setVisibility(View.GONE);
    }
}
